<?php

namespace App\Http\Controllers\Business;


use App\Events\Event;
use App\Events\AppointEvent;
use App\Model\Business\AppointLevel;
use App\Model\Foundation\TeachLevel;
use App\Model\Marketing\Order;
use App\Model\Marketing\Product;
use App\Model\System\Organization;
use Illuminate\Http\Request;
use App\Model\Business\Schedule;
use App\Model\Foundation\Student;
use App\Model\Foundation\Teacher;
use App\Model\Business\Appointment;
use App\Model\System\Token;
use App\Http\Controllers\MessagePacket;
use App\Model\Business\ScheduleStuden;
use App\Model\Business\AppointmentSchedule;
use Illuminate\Support\Facades\DB;
use Laravel\Lumen\Routing\Controller as BaseController;
use Mockery\CountValidator\Exception;


/**
 * 处理正式预约课
 * Class AppointmentController
 * @package App\Http\Controllers\Business
 */
class  AppointmentController extends BaseController
{
    use MessagePacket;

    protected $levels;

    /**
     * 获取单一正式预约的信息
     * @param $id
     * @return packetMessage
     */
    function getOne($id)
    {
        $id = intval($id);
        $appoint = Appointment::find($id);
        if(empty($appoint)){
            return $this->fail($appoint, '数据不存在');
        }
        $classinno = Student::where('studentuid',$appoint->studentuid)->pluck('ClassInNo')->first();
        $appoint->ClassInNo = $classinno;
        return $this->success($appoint);
    }


    /**
     * 批量查询正式预约
     * @param Request $request
     * @return packetMessage
     */
    function getAll(Request $request)
    {
        $items = Appointment::getAll($request);
        if($request->has('page')){
            $data['list'] = $items['data'];
            unset($items['data']);
            $data['pager'] = $items;
        }else{
            $data['list'] = $items;
        }

        foreach ($data['list'] as $k=>$vs){
	    $vs->classhours = round($vs->classhours,1);
            $vs->classbonus = round($vs->classbonus,1);
            $vs->consumed = round($vs->consumed,1);
            if(intval($vs->classhours)*100 == ($vs->classhours*100)){
                $data['list'][$k]->classhours = intval($vs->classhours);
            }
            if(intval($vs->classbonus)*100 == ($vs->classbonus*100)){
                $data['list'][$k]->classbonus = intval($vs->classbonus);
            }
            if(intval($vs->consumed)*100 == ($vs->consumed*100)){
                $data['list'][$k]->consumed = intval($vs->consumed);
            }
            $data['list'][$k]->resthours = $data['list'][$k]->classhours + $data['list'][$k]->classbonus - $data['list'][$k]->consumed;
            $data['list'][$k]->resthours = round($data['list'][$k]->resthours,1);
            if(intval($data['list'][$k]->resthours)*100 == ($data['list'][$k]->resthours*100)){
                $data['list'][$k]->resthours = intval($data['list'][$k]->resthours);
            }
        }
        if(empty($data['list'])){
            return $this->fail($data, '数据不存在');
        }
        if($request->has('page')){
            return $this->success($data);
        }else{
            return $this->success($data['list']);
        }

    }


    /**
     * 添加一个正式预约
     * @param Request $request
     * @return packetMessage
     */
    function  create(Request $request)
    {
        try {
            $fields = $request->all();
	        if (empty($fields)) {
                $this->fail(false, '数据不全');
            }
            $fields['status'] = 0;
            $appoint = new Appointment($fields);
            $appoint->creator = Token::user()->username;
            $appoint->created_by = Token::user()->userid;
            $appoint->updated_by = Token::user()->userid;
            $appoint->save();

//            # 更新订单信息
//            $order = Order::find($request->get('orderid'));
//            $order->status = Order::ASSIGNED;
//            $order->save();

            return $this->success($appoint);
        }catch (\Exception $e){
            if($appoint instanceof Appointment){
                $appoint->delete();
            }
            return $this->fail(false, '保存失败: '.$e->getMessage());
        }
    }


    /**
     * 更新某个正式预约的信息
     * @param Request $request
     * @return packetMessage
     */
    function  update(Request $request, $id=null)
    {
        $obj = Appointment::find($id);
        $obj->update($request->all());
        $obj->updated_by = Token::user()->userid;

        if($obj->save()){
            return $this->success($obj);
        }else{
            return $this->fail(false,'保存失败');
        }
    }


    /**
     * 删除某个时间
     * @param $id
     * @return packetMessage
     */
    function  delete($id)
    {
        try{
	    $relations = AppointmentSchedule::where('appointid',$id)->get();
            if($relations) {
                $appoint = Appointment::find($id);
                foreach ($relations as $relation) {

                    $schedule = Schedule::find($relation->scheduleid);
                    if ($appoint) {

                        # 触发接口事件
                        $this->dispatchEvent($schedule, Event::STUDENT, $appoint->studentuid, true);

                        # 移除学生，课程关系
                        ScheduleStuden::delRelation($schedule->scheduleid, $appoint->studentuid);

                        # 更新schedule
                        $schedule->unppoint();
                    }
                    # 移除
                    AppointmentSchedule::destroy($relation->id);
                    # 检测是否课程为空
                    if (env('ASYN_MODE')) {
                        if ($schedule->usequotas <= 0) {
                            $this->dispatchEvent($schedule, Event::DELETE);
                        }
                    }
                }
                if (!empty($appoint->orderid)) {
                    $order = Order::find($appoint->orderid);
                    $order->status = Order::PAID;
                    $order->save();
                }
                $appoint->delete();
                return $this->success(true, '删除约课及学生信息成功');
            }
        }catch (\Exception $e){
            return $this->fail(false,'删除失败'.$e->getMessage());
        }
    }

    /**
     *
     * @param Request $request
     * @param $id
     * @return array
     *
     */

    function appint(Request $request, $id)
    {
        try{
            # 关闭自动提交
            DB::beginTransaction();
            # 加锁
            $appoint = Appointment::lockForUpdate()->find($id);
            if($appoint->consumed >= ($appoint->classhours + $appoint->classbonus)){
                throw  new \Exception('课时数不足');
            }
            $schedule = Schedule::lockForUpdate()->find($request->scheduleid);
            if($schedule->quotas <= $schedule->usequotas){
                throw  new \Exception('名额已满');
            }
            #验证是否重复预约
            $student = AppointmentSchedule::lockForUpdate()->where('scheduleid',$request->get('scheduleid'))
                ->where('appointid',$id)
                ->first();
            if(!empty($student)){
                throw  new \Exception('预约失败:当前学生已存在该课下的预约记录');
            }

            #触发接口事件
            $this->dispatchEvent($schedule,Event::STUDENT, $appoint->studentuid);

            $teacher = Teacher::find($schedule->teacheruid);

            # 更新关系
            $relation = new AppointmentSchedule();
            $relation->appointid = $appoint->appointid;
            $relation->scheduleid = $schedule->scheduleid;
            $relation->begintime = $schedule->begintime;
            $relation->endtime = $schedule->endtime;
            $relation->teacher = $teacher->lastname;
            $relation->coursetype = $schedule->coursetypename;
            $relation->coursetypeid = $schedule->coursetypeid;
            $relation->save();
            # 更新schedule
            $schedule->appoint($id);
            # 更新 resume个数
            $appoint->appoint($schedule->realSchedules());
            # 添加学生，课程关系
            ScheduleStuden::addRelation($schedule->scheduleid, $appoint->studentuid);

            DB::commit();
            return $this->success(true);
        }catch (\Exception $e){
            DB::rollBack();
            return $this->fail(false, '预约失败:'.$e->getMessage());
        }
    }

//
//    /**
//     * 弃用
//     * @param Request $request
//     * @param $id
//     * @return packetMessage
//     * @throws
//     */
//    function  _appint(Request $request, $id)
//    {
//        try{
//            $appoint = Appointment::find($id);
//            if($appoint->consumed >= ($appoint->classhours + $appoint->classbonus)){
//                return $this->fail(false,'课时数不足');
//            }
//            $schedule = Schedule::find($request->scheduleid);
//            if($schedule->quotas <= $schedule->usequotas){
//                return $this->fail(false, '名额已满');
//            }
//	          #验证是否重复预约
//            $student = AppointmentSchedule::where('scheduleid',$request->get('scheduleid'))
//                ->where('appointid',$id)
//                ->first();
//            if(!empty($student)){
//                return $this->fail(false, '预约失败:当前学生已存在该课下的预约记录');
//            }
//            $teacher = Teacher::find($schedule->teacheruid);
//
//            #触发接口事件
//            $this->dispatchEvent($schedule,Event::STUDENT, $appoint->studentuid);
//
//            # 更新关系
//            $relation = new AppointmentSchedule();
//            $relation->appointid = $appoint->appointid;
//            $relation->scheduleid = $schedule->scheduleid;
//            $relation->begintime = $schedule->begintime;
//            $relation->endtime = $schedule->endtime;
//            $relation->teacher = $teacher->lastname;
//            $relation->coursetype = $schedule->coursetypename;
//            $relation->coursetypeid = $schedule->coursetypeid;
//            $relation->save();
//            # 更新schedule
//            $schedule->appoint();
//            # 更新 resume个数
//            $appoint->appoint($schedule->realSchedules());
//            # 添加学生，课程关系
//            ScheduleStuden::addRelation($schedule->scheduleid, $appoint->studentuid);
//
//            return $this->success(true);
//        }catch (\Exception $e){
//            throw $e;
//            return $this->fail(false, '预约失败:'.$e->getMessage());
//        }
//    }


    /**
     * 取消预约
     * @param Request $request
     * @param $id
     * @return packetMessage
     */
    function unappoint(Request $request, $id)
    {
        try{
            $now = time();
            $relation = AppointmentSchedule::find($id);
            if($now > strtotime($relation->begintime)){
                return $this->fail(false, '取消预约失败:已经开始上课');
            }
            $appoint = Appointment::find($relation->appointid);
            $schedule = Schedule::find($relation->scheduleid);

            # 触发接口事件
            $this->dispatchEvent($schedule,Event::STUDENT, $appoint->studentuid, true);

            # 移除学生，课程关系
            ScheduleStuden::delRelation($schedule->scheduleid, $appoint->studentuid);
            # 更新schedule
            $schedule->unppoint($id);
            # 更新 resume个数
            $appoint->unppoint($schedule->realSchedules());
            # 移除
            AppointmentSchedule::destroy($id);

            # 检测是否课程为空
            if(env('ASYN_MODE')){
                if($schedule->usequotas <= 0){
                    $this->dispatchEvent($schedule,Event::DELETE);
                }
            }

            return $this->success(true);
        }catch (\Exception $e){
            return $this->fail(false, '取消预约失败:'.$e->getMessage());
        }
    }


    /**
     * 预约列表
     * @param Request $request
     * @param $id
     * @return packetMessage
     */
    function getAppointList(Request $request, $id)
    {
        $items = AppointmentSchedule::where('appointid', $id)->get();

        if(empty($items)){
            return $this->fail([], '数据不存在');
        }
        return $this->success($items);
    }

    /**
     * 获取某个学生的约课课程
     * @param Request $request
     * @param $id
     * @return packetMessage
     */
    function getMyAppointsForStudent(Request $request, $id)
    {
        $data = [];
        $appints = Appointment::where('studentuid', $id)->get()->toarray();

        foreach ($appints as $app){
            $info['appoint'] = $app;
            if($app['orderid']){
                $productid = Order::where('id',$app['orderid'])->value('productid');
                if($productid){
                    $products = Product::where('id',$productid)->get();
                    foreach($products as $product){
                        $product->master = Teacher::where('teacheruid',$product->master)->value('lastname');
                    }
                    $info['product'] = $products;
                }
            }
            $info['appoint']['levels'] = AppointLevel::where('appointid',$app['appointid'])->pluck('levelid')->toarray();
            $data[] = $info;
        }
        return $this->success($data);
    }


    /**
     * 获取学生约课的课节列表
     * @param Request $request
     * @param $id
     * @return array
     */
    function getAppointLessons(Request $request, $id)
    {
        try{
            $scheduleids = AppointmentSchedule::where('appointid', $id)->pluck('scheduleid')->toarray();
            $schedules = Schedule::find($scheduleids);
            return $this->success($schedules);
        }catch (\Exception $e){
            return $this->fail(false, $e->getMessage());
        }
    }

    /**
     * 获取某个学生即将开课的约课课程
     * @param $id
     * @return packetMessage
     */
    function getMyRecentlyAppointsForStudent($id){
        $currentTime = date('Y-m-d H:i:s');
        $appointids = Appointment::where('studentuid',$id)->pluck('appointid');

        $data = [];
        if(!empty($appointids)){
            $schedule = AppointmentSchedule::whereIn('appointid',$appointids)
                ->where('begintime','>=',$currentTime)->orderBy('begintime')->limit(1)->first();

            if(!empty($schedule)){
                $scheduleid = $schedule->scheduleid;
                $appointid = $schedule->appointid;
                $appoint = Appointment::where('appointid',$appointid)->first();
                $course = $appoint->coursename;

                ##获取图片
                $product = DB::table('appointments')
                    ->select('products.*')
                    ->where('appointments.appointid',$appointid)
                    ->join('orders', 'orders.id', '=', 'appointments.orderid')
                    ->join('products', 'orders.productid', '=', 'products.id')->first();

                if(!empty($product)){
                    $img = $product->cover;
                }
                else{
                    $img = Organization::defaultImage;
                }

                ##获取教师
                $schedule = Schedule::where('scheduleid',$scheduleid)->first();
                if(!empty($schedule)){
                    $teacher = Teacher::where('teacheruid',$schedule->teacheruid)->value('lastname');
                }
                else{
                    $teacher = [];
                }

                $course = Appointment::where('appointid',$appointid)->value('coursename');
                $product = [
                    'img' => $img,
                    'course' => $course,
                    'teacher' => $teacher
                ];

                $data['schedule'] = $schedule;
                $data['product'] = $product;
                return $this->success($data);
            }
        }
        return $this->fail($data, '数据不存在');
    }


    /**
     * 给约课单，分配level
     * @param Request $request
     * @param $id
     * @throws \Exception
     * @return array
     */
    function setAppointLevels(Request $request, $id)
    {
        try{
            if(!$request->has('levels') and !$request->has('count')){
                throw new \Exception('缺少参数');
            }
            # 删除老的
            $count = $request->get('count');
            $levels = $request->get('levels');
            if(count($levels)>=0 or $count==0){
                AppointLevel::where('appointid', $id)->delete();
            }
            # 添加新的
            foreach($levels as $level){
                $obj = new AppointLevel(['appointid'=>$id, 'levelid'=>$level]);
                $obj->save();
            }
            return $this->success(true);
        }catch (\Exception $e){
            return $this->fail(false, $e->getMessage());
        }
    }

    /**
     * 获取约课单level
     * @param Request $request
     * @param $id
     * @throws \Exception
     * @return array
     */
    function getAppointLevels(Request $request, $id)
    {
        try{
//            $this->levels = [];
            $lids = AppointLevel::where('appointid', $id)->pluck('levelid');
            $objs = TeachLevel::find($lids);
            return $this->success($objs);
//            foreach ($lids as $lid){
//                $this->getLevels($lid);
//            }
//            return $this->success($this->levels);
        }catch (\Exception $e){
            return $this->fail(false, $e->getMessage());
        }
    }

    /**
     * 遍历levels
     * @param Request $request
     * @param $id
     * @throws \Exception
     * @return array
     */
    protected function getLevels($lid)
    {
        try{
            $this->levels[] = TeachLevel::find($lid);
            $childs = TeachLevel::where('pid',$lid)->get();
            if($childs){
                foreach ($childs as $child){
                    $this->getLevels($child->id);
                }
            }

        }catch (\Exception $e){
            return $this->fail(false, $e->getMessage());
        }
    }


    /**
     * 抛出事件
     * @param $schedule
     * @param $studentid
     * @param bool $old
     * @return mixed
     * @throws \Exception
     */
    protected function dispatchEvent($schedule,$action,$studentid=null, $old=false)
    {
        try{
            $event = new AppointEvent($schedule, $action);
	        if($studentid){
                $student = Student::find($studentid);
                $event->setIdentity(1);
                $event->setStudent($student, $old);
            }
            event($event);
        }catch (\Exception $e){
            throw $e;
            return $e->getMessage();
        }
    }

}
